/* Copyright (C) 1996-2000,2003,2004,2007 Free Software Foundation, Inc.
   This file is part of the GNU C Library.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

/*
 * ISO/IEC 9945-1:1996 6.7: Asynchronous Input and Output
 */

module linux.aio;

private import core.sys.posix.signal;

alias long __off64_t;
alias int  __off_t;

extern(C):

/* Asynchronous I/O control block.  */
struct aiocb
{
  int aio_fildes;       /* File desriptor.  */
  int aio_lio_opcode;       /* Operation to be performed.  */
  int aio_reqprio;      /* Request priority offset.  */
  void *aio_buf;    /* Location of buffer.  */
  size_t aio_nbytes;        /* Length of transfer.  */
  sigevent aio_sigevent;    /* Signal number and value.  */

  /* Internal members.  */
  aiocb *__next_prio;
  int __abs_prio;
  int __policy;
  int __error_code;
  ssize_t __return_value;

  union {
      struct V64 {
          __off64_t aio_offset;
      };
      V64 v64;
      struct V32{
          __off_t aio_offset;
      };
      V32 v32;
  }
  char __unused[32];
};

/* The same for the 64bit offsets.  Please note that the members aio_fildes
   to __return_value have to be the same in aiocb and aiocb64.  */
version (__USE_LARGEFILE64) {
struct aiocb64
{
  int aio_fildes;       /* File desriptor.  */
  int aio_lio_opcode;       /* Operation to be performed.  */
  int aio_reqprio;      /* Request priority offset.  */
  void *aio_buf;    /* Location of buffer.  */
  size_t aio_nbytes;        /* Length of transfer.  */
  sigevent aio_sigevent;    /* Signal number and value.  */

  /* Internal members.  */
  aiocb *__next_prio;
  int __abs_prio;
  int __policy;
  int __error_code;
  ssize_t __return_value;

  __off64_t aio_offset;     /* File offset.  */
  char __unused[32];
};
} // version(__USE_LARGEFILE64)


/* To customize the implementation one can use the following struct.
   This implementation follows the one in Irix.  */
struct aioinit
  {
    int aio_threads;        /* Maximal number of threads.  */
    int aio_num;        /* Number of expected simultanious requests. */
    int aio_locks;      /* Not used.  */
    int aio_usedba;     /* Not used.  */
    int aio_debug;      /* Not used.  */
    int aio_numusers;       /* Not used.  */
    int aio_idle_time;      /* Number of seconds before idle thread
                   terminates.  */
    int aio_reserved;
  };


/* Return values of cancelation function.  */
enum
{
  AIO_CANCELED,
  AIO_NOTCANCELED,
  AIO_ALLDONE
};


/* Operation codes for `aio_lio_opcode'.  */
enum
{
  LIO_READ,
  LIO_WRITE,
  LIO_NOP
};


/* Synchronization options for `lio_listio' function.  */
enum
{
  LIO_WAIT,
  LIO_NOWAIT
};


/* Allow user to specify optimization.  */
void aio_init (const aioinit *__init);

version(__USE_FILE_OFFSET64) {
    alias aio_read aio_read64;
    alias aio_write aio_write64;
    alias lio_listio lio_listio64;
    alias aio_error aio_error64;
    alias aio_return aio_return64;
    alias aio_cancel aio_cancel64;
    alias aio_suspend aio_suspend64;
    alias aio_fsync aio_fsync64;
}
else {
    /* Enqueue read request for given number of bytes and the given priority.  */
    int aio_read (aiocb *__aiocbp);
    /* Enqueue write request for given number of bytes and the given priority.  */
    int aio_write (aiocb *__aiocbp);

    /* Initiate list of I/O requests.  */
    int lio_listio (int __mode,
                   const(aiocb *)* __list,
                   int __nent, sigevent *__sig);

    /* Retrieve error status associated with AIOCBP.  */
    int aio_error (const aiocb *__aiocbp);
    /* Return status associated with AIOCBP.  */
    ssize_t aio_return (aiocb *__aiocbp);

    /* Try to cancel asynchronous I/O requests outstanding against file
       descriptor FILDES.  */
    int aio_cancel (int __fildes, aiocb *__aiocbp);

    /* Suspend calling thread until at least one of the asynchronous I/O
       operations referenced by LIST has completed.

       This function is a cancellation point and therefore not marked with
       __THROW.  */
    int aio_suspend (const(const (aiocb) *) __list[], int __nent,
                const timespec *__timeout);

    /* Force all operations associated with file desriptor described by
       `aio_fildes' member of AIOCBP.  */
    int aio_fsync (int __operation, aiocb *__aiocbp);
}

version (__USE_LARGEFILE64) {
    int aio_read64 (aiocb64 *__aiocbp);
    int aio_write64 (aiocb64 *__aiocbp);

    int lio_listio64 (int __mode,
                 const(aiocb64 *)* __list,
                 int __nent, sigevent *__sig);

    int aio_error64 (const aiocb64 *__aiocbp);
    ssize_t aio_return64 (aiocb64 *__aiocbp);

    int aio_cancel64 (int __fildes, aiocb64 *__aiocbp);

    int aio_suspend64 (const(const(aiocb64) *) __list[], int __nent,
                  const(timespec) *__timeout);

    int aio_fsync64 (int __operation, aiocb64 *__aiocbp);
}

